#region " LICENSE "
// DRILL - Dependency Resolution Interface Layer Library
// Copyright (c) 2008-2012 Wade A. Reynolds. All rights reserved.
// http://drill.codeplex.com/
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;

namespace Drill.Core.Utilities
{
    [TestFixture]
    public class PathUtilityTests
    {
        private static readonly char[] _whitespaceChars = new[] { ' ', '\0', '\f', '\n', '\r', '\t' };

        [Category("UnitTest")]
        [Test]
        public void CurrentDirectoryRelativePathPartEqualsPeriod()
        {
            const string expectedValue = ".";

            Assert.That(PathUtility.CurrentDirectoryRelativePathPart, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void ParentDirectoryRelativePathPartEqualsPeriodPeriod()
        {
            const string expectedValue = "..";

            Assert.That(PathUtility.ParentDirectoryRelativePathPart, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetAltDirectorySeparator()
        {
            string expectedValue = Path.AltDirectorySeparatorChar.ToString();

            Assert.That(PathUtility.AltDirectorySeparator, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetAltDirectorySeparatorChar()
        {
            char expectedValue = Path.AltDirectorySeparatorChar;

            Assert.That(PathUtility.AltDirectorySeparatorChar, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetDirectorySeparator()
        {
            string expectedValue = Path.DirectorySeparatorChar.ToString();

            Assert.That(PathUtility.DirectorySeparator, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetDirectorySeparatorChar()
        {
            char expectedValue = Path.DirectorySeparatorChar;

            Assert.That(PathUtility.DirectorySeparatorChar, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetPathSeparator()
        {
            char expectedValue = Path.PathSeparator;

            Assert.That(PathUtility.PathSeparator, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetPathSeparatorString()
        {
            string expectedValue = Path.PathSeparator.ToString();

            Assert.That(PathUtility.PathSeparatorString, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetVolumeSeparator()
        {
            string expectedValue = Path.VolumeSeparatorChar.ToString();

            Assert.That(PathUtility.VolumeSeparator, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetVolumeSeparatorChar()
        {
            char expectedValue = Path.VolumeSeparatorChar;

            Assert.That(PathUtility.VolumeSeparatorChar, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetWebDirectorySeparator()
        {
            const string expectedValue = @"/";

            Assert.That(PathUtility.WebDirectorySeparator, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetWebDirectorySeparatorChar()
        {
            const char expectedValue = '/';

            Assert.That(PathUtility.WebDirectorySeparatorChar, Is.EqualTo(expectedValue));
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanCombineArrayOfPathParts")]
        public string CanCombineArrayOfPathParts(params string[] paths)
        {
            string value = PathUtility.Combine(paths);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanCombineArrayOfPathParts
        {
            get
            {
                yield return new TestCaseData(new[] {new string[] {}}).Returns(string.Empty);
                yield return new TestCaseData(new[] { new string[] { null } })
                    .Throws(typeof(ArgumentNullException));
                
                yield return new TestCaseData(new[] { new[] { "" } }).Returns(string.Empty);
                yield return new TestCaseData(new[] { new[] { "", "" } }).Returns(string.Empty);
                yield return new TestCaseData(new[] { new[] { "", "", "" } }).Returns(string.Empty);
                yield return new TestCaseData(new[] { new[] { "", "", "", "" } }).Returns(string.Empty);
                yield return new TestCaseData(new[] { new[] { "", "", "", "", "" } }).Returns(string.Empty);
                yield return new TestCaseData(new[] { new[] { "", "", "", "", "", "" } }).Returns(string.Empty);
                yield return new TestCaseData(new[] { new[] { "", "", "", null, "", "" } })
                    .Throws(typeof(ArgumentNullException));
                
                yield return new TestCaseData(new[] { new[] { "a", "b" } }).Returns(@"a\b");
                yield return new TestCaseData(new[] { new[] { "a", "b", "c" } }).Returns(@"a\b\c");
                yield return new TestCaseData(new[] { new[] { "a", "b", "c", "d" } }).Returns(@"a\b\c\d");
                yield return new TestCaseData(new[] { new[] { "a", "b", "c", "d", "e" } }).Returns(@"a\b\c\d\e");
                yield return new TestCaseData(new[] { new[] { "a", "b", "c", "d", "e", "f" } }).Returns(@"a\b\c\d\e\f");
                yield return new TestCaseData(new[] { new[] { "a", "b", "c", "d", "e", "f", "g" } }).Returns(@"a\b\c\d\e\f\g");
                
                yield return new TestCaseData(new[] { new[] { @"C:\a", @"b" } }).Returns(@"C:\a\b");
                yield return new TestCaseData(new[] { new[] { @"C:\a", @"b\c\d" } }).Returns(@"C:\a\b\c\d");
                yield return new TestCaseData(new[] { new[] { @"C:\a", @"b\c\d", @"e\f" } }).Returns(@"C:\a\b\c\d\e\f");
                yield return new TestCaseData(new[] { new[] { @"C:\a", @"b\c\d", @"e\f", @"g\h\i" } }).Returns(@"C:\a\b\c\d\e\f\g\h\i");
                
                yield return new TestCaseData(new[] { new[] { "a/b", "c" } }).Returns(@"a/b\c");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanCombineTwoPathParts")]
        public string CanCombineTwoPathParts(string path1, string path2)
        {
            string value = PathUtility.Combine(path1, path2);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanCombineTwoPathParts
        {
            get
            {
                yield return new TestCaseData(null, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", "").Returns(string.Empty);
                yield return new TestCaseData("a", "b").Returns(@"a\b");
                yield return new TestCaseData("asdf", "zxcvbnm").Returns(@"asdf\zxcvbnm");
                yield return new TestCaseData(@"as\df", @"zxc\vbn\m").Returns(@"as\df\zxc\vbn\m");
                yield return new TestCaseData("a/b", "c").Returns(@"a/b\c");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanCombineThreePathParts")]
        public string CanCombineThreePathParts(string path1, string path2, string path3)
        {
            string value = PathUtility.Combine(path1, path2, path3);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanCombineThreePathParts
        {
            get
            {
                yield return new TestCaseData(null, null, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", null, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, "", null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, null, "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, "", "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", null, "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", "", null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", "", "").Returns(string.Empty);
                yield return new TestCaseData("a", "b", "c").Returns(@"a\b\c");
                yield return new TestCaseData("asdf", "zxcvbnm", "qwerty").Returns(@"asdf\zxcvbnm\qwerty");
                yield return new TestCaseData(@"as\df", @"zxc\vbn\m", @"qwer\ty").Returns(@"as\df\zxc\vbn\m\qwer\ty");
                yield return new TestCaseData(@"a/b", @"c", @"d/e\f").Returns(@"a/b\c\d/e\f");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanCombineFourPathParts")]
        public string CanCombineFourPathParts(string path1, string path2, string path3, string path4)
        {
            string value = PathUtility.Combine(path1, path2, path3, path4);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanCombineFourPathParts
        {
            get
            {
                yield return new TestCaseData(null, null, null, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", null, null, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, "", null, null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, null, "", null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, null, null, "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData(null, "", "", "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", null, "", "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", "", null, "").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", "", "", null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", "", "", "").Returns(string.Empty);
                yield return new TestCaseData("a", "b", "c", "d").Returns(@"a\b\c\d");
                yield return new TestCaseData("asdf", "zxcvbnm", "qwerty", "plokijuhyg").Returns(@"asdf\zxcvbnm\qwerty\plokijuhyg");
                yield return new TestCaseData(@"as\df", @"zxc\vbn\m", @"qwer\ty", @"p\l\oki/juh\y\g").Returns(@"as\df\zxc\vbn\m\qwer\ty\p\l\oki/juh\y\g");
                yield return new TestCaseData(@"a/b", @"c", @"d/e\f", @"g/h/i").Returns(@"a/b\c\d/e\f\g/h/i");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetDirectoryName")]
        public string CanGetDirectoryName(string path)
        {
            string value = PathUtility.GetDirectoryName(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetDirectoryName
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Throws(typeof (ArgumentException));
                yield return new TestCaseData("a").Returns(string.Empty);
                yield return new TestCaseData(@"a\b").Returns("a");
                yield return new TestCaseData(@"a\b\").Returns(@"a\b");
                yield return new TestCaseData(@"a\b\c").Returns(@"a\b");
                yield return new TestCaseData(@"a\b\c\").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\b\c\d").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\b\c\d\").Returns(@"a\b\c\d");
                yield return new TestCaseData(@"a\b\c\d\\").Returns(@"a\b\c\d");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetExtension")]
        public string CanGetExtension(string path)
        {
            string value = PathUtility.GetExtension(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetExtension
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Returns(string.Empty);
                yield return new TestCaseData(".").Returns(string.Empty);
                yield return new TestCaseData("..").Returns(string.Empty);
                yield return new TestCaseData("...").Returns(string.Empty);
                yield return new TestCaseData("....").Returns(string.Empty);
                yield return new TestCaseData(".....").Returns(string.Empty);
                yield return new TestCaseData("a").Returns(string.Empty);
                yield return new TestCaseData("a.").Returns(string.Empty);
                yield return new TestCaseData(".a").Returns(".a");
                yield return new TestCaseData(".ab").Returns(".ab");
                yield return new TestCaseData(".abc").Returns(".abc");
                yield return new TestCaseData(".abcd").Returns(".abcd");
                yield return new TestCaseData(".abcde").Returns(".abcde");
                yield return new TestCaseData(".abcdef").Returns(".abcdef");
                yield return new TestCaseData("0.a").Returns(".a");
                yield return new TestCaseData("0.ab").Returns(".ab");
                yield return new TestCaseData("0.abc").Returns(".abc");
                yield return new TestCaseData("0.abcd").Returns(".abcd");
                yield return new TestCaseData("0.abcde").Returns(".abcde");
                yield return new TestCaseData("0.abcdef").Returns(".abcdef");
                yield return new TestCaseData("a.b").Returns(".b");
                yield return new TestCaseData("a.b.c").Returns(".c");
                yield return new TestCaseData("filename.ext").Returns(".ext");
                yield return new TestCaseData(@"dir\filename.ext").Returns(".ext");
                yield return new TestCaseData("dotted.filename.ext").Returns(".ext");
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(".ext");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetFileName")]
        public string CanGetFileName(string path)
        {
            string value = PathUtility.GetFileName(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetFileName
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Returns(string.Empty);
                yield return new TestCaseData(".").Returns(".");
                yield return new TestCaseData("..").Returns("..");
                yield return new TestCaseData("...").Returns("...");
                yield return new TestCaseData("....").Returns("....");
                yield return new TestCaseData(".....").Returns(".....");
                yield return new TestCaseData("a").Returns("a");
                yield return new TestCaseData("a.").Returns("a.");
                yield return new TestCaseData(".a").Returns(".a");
                yield return new TestCaseData(".ab").Returns(".ab");
                yield return new TestCaseData(".abc").Returns(".abc");
                yield return new TestCaseData(".abcd").Returns(".abcd");
                yield return new TestCaseData(".abcde").Returns(".abcde");
                yield return new TestCaseData(".abcdef").Returns(".abcdef");
                yield return new TestCaseData("0.a").Returns("0.a");
                yield return new TestCaseData("0.ab").Returns("0.ab");
                yield return new TestCaseData("0.abc").Returns("0.abc");
                yield return new TestCaseData("0.abcd").Returns("0.abcd");
                yield return new TestCaseData("0.abcde").Returns("0.abcde");
                yield return new TestCaseData("0.abcdef").Returns("0.abcdef");
                yield return new TestCaseData("a.b").Returns("a.b");
                yield return new TestCaseData("a.b.c").Returns("a.b.c");
                yield return new TestCaseData("filename.ext").Returns("filename.ext");
                yield return new TestCaseData(@"dir\filename.ext").Returns("filename.ext");
                yield return new TestCaseData("dotted.filename.ext").Returns("dotted.filename.ext");
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns("dotted.filename.ext");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetFileNameWithoutExtension")]
        public string CanGetFileNameWithoutExtension(string path)
        {
            string value = PathUtility.GetFileNameWithoutExtension(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetFileNameWithoutExtension
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Returns(string.Empty);
                yield return new TestCaseData(".").Returns(string.Empty);
                yield return new TestCaseData("..").Returns(".");
                yield return new TestCaseData("...").Returns("..");
                yield return new TestCaseData("....").Returns("...");
                yield return new TestCaseData(".....").Returns("....");
                yield return new TestCaseData("a").Returns("a");
                yield return new TestCaseData("a.").Returns("a");
                yield return new TestCaseData(".a").Returns(string.Empty);
                yield return new TestCaseData(".ab").Returns(string.Empty);
                yield return new TestCaseData(".abc").Returns(string.Empty);
                yield return new TestCaseData(".abcd").Returns(string.Empty);
                yield return new TestCaseData(".abcde").Returns(string.Empty);
                yield return new TestCaseData(".abcdef").Returns(string.Empty);
                yield return new TestCaseData("0.a").Returns("0");
                yield return new TestCaseData("0.ab").Returns("0");
                yield return new TestCaseData("0.abc").Returns("0");
                yield return new TestCaseData("0.abcd").Returns("0");
                yield return new TestCaseData("0.abcde").Returns("0");
                yield return new TestCaseData("0.abcdef").Returns("0");
                yield return new TestCaseData("a.b").Returns("a");
                yield return new TestCaseData("a.b.c").Returns("a.b");
                yield return new TestCaseData("filename.ext").Returns("filename");
                yield return new TestCaseData(@"dir\filename.ext").Returns("filename");
                yield return new TestCaseData("dotted.filename.ext").Returns("dotted.filename");
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns("dotted.filename");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetFullPath")]
        public string CanGetFullPath(string path)
        {
            string value = PathUtility.GetFullPath(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetFullPath
        {
            get
            {
                yield return new TestCaseData(null).Throws(typeof (ArgumentNullException));
                yield return new TestCaseData("").Throws(typeof (ArgumentException));
                yield return new TestCaseData(".").Returns(Environment.CurrentDirectory);
                
                // ReSharper disable PossibleNullReferenceException
                yield return new TestCaseData("..").Returns(new DirectoryInfo(Environment.CurrentDirectory).Parent.FullName);
                yield return new TestCaseData(@"..\").Returns(new DirectoryInfo(Environment.CurrentDirectory).Parent.FullName + @"\");
                yield return new TestCaseData(@"..\..").Returns(new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName);
                yield return new TestCaseData(@"..\..\").Returns(new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName + @"\");
                // ReSharper restore PossibleNullReferenceException

                yield return new TestCaseData("a").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\a");
                yield return new TestCaseData("a.").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\a");
                yield return new TestCaseData(".a").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\.a");
                yield return new TestCaseData(".ab").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\.ab");
                yield return new TestCaseData(".abc").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\.abc");
                yield return new TestCaseData(".abcd").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\.abcd");
                yield return new TestCaseData(".abcde").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\.abcde");
                yield return new TestCaseData(".abcdef").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\.abcdef");

                yield return new TestCaseData("0.a").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\0.a");
                yield return new TestCaseData("0.ab").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\0.ab");
                yield return new TestCaseData("0.abc").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\0.abc");
                yield return new TestCaseData("0.abcd").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\0.abcd");
                yield return new TestCaseData("0.abcde").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\0.abcde");
                yield return new TestCaseData("0.abcdef").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\0.abcdef");

                yield return new TestCaseData("a.b").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\a.b");
                yield return new TestCaseData("a.b.c").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\a.b.c");
                yield return new TestCaseData("filename.ext").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\filename.ext");
                yield return new TestCaseData(@"dir\filename.ext").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\dir\filename.ext");
                yield return new TestCaseData("dotted.filename.ext").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\dotted.filename.ext");
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(new DirectoryInfo(Environment.CurrentDirectory).FullName + @"\dir\dotted.filename.ext");
            }
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetInvalidFileNameChars()
        {
            char[] invalidChars = PathUtility.GetInvalidFileNameChars();

            Assert.That(invalidChars, Is.Not.Null);
            Assert.That(invalidChars.Length, Is.GreaterThan(0));
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetInvalidPathChars()
        {
            char[] invalidChars = PathUtility.GetInvalidPathChars();

            Assert.That(invalidChars, Is.Not.Null);
            Assert.That(invalidChars.Length, Is.GreaterThan(0));
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetPathRoot")]
        public string CanGetPathRoot(string path)
        {
            string value = PathUtility.GetPathRoot(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetPathRoot
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Throws(typeof (ArgumentException));
                yield return new TestCaseData(".").Returns(string.Empty);
                yield return new TestCaseData("..").Returns(string.Empty);
                yield return new TestCaseData("...").Returns(string.Empty);
                yield return new TestCaseData("....").Returns(string.Empty);
                yield return new TestCaseData(".....").Returns(string.Empty);
                yield return new TestCaseData("a").Returns(string.Empty);
                yield return new TestCaseData("a.").Returns(string.Empty);
                yield return new TestCaseData(".a").Returns(string.Empty);
                yield return new TestCaseData(".ab").Returns(string.Empty);
                yield return new TestCaseData(".abc").Returns(string.Empty);
                yield return new TestCaseData(".abcd").Returns(string.Empty);
                yield return new TestCaseData(".abcde").Returns(string.Empty);
                yield return new TestCaseData(".abcdef").Returns(string.Empty);
                yield return new TestCaseData("filename.ext").Returns(string.Empty);
                yield return new TestCaseData(@"dir\filename.ext").Returns(string.Empty);
                yield return new TestCaseData("dotted.filename.ext").Returns(string.Empty);
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(string.Empty);
                yield return new TestCaseData(@"file://").Returns(string.Empty);
                yield return new TestCaseData(@"file://a").Returns(string.Empty);
                yield return new TestCaseData(@"file://a/").Returns(string.Empty);

                yield return new TestCaseData("C:").Returns("C:");
                yield return new TestCaseData(@"C:\").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\c").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\c\").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\c\d").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\c\d\").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\c\d\e").Returns(@"C:\");
                yield return new TestCaseData(@"C:\a\b\c\d\e\").Returns(@"C:\");

                yield return new TestCaseData(@"\").Returns(@"\");
                yield return new TestCaseData(@"\a").Returns(@"\");
                yield return new TestCaseData(@"\a\b").Returns(@"\");
                yield return new TestCaseData(@"\a\b\c").Returns(@"\");
                yield return new TestCaseData(@"\a\b\c\d").Returns(@"\");
                yield return new TestCaseData(@"\\").Returns(@"\\");
                yield return new TestCaseData(@"\\a").Returns(@"\\a");
                yield return new TestCaseData(@"\\a\").Returns(@"\\a\");
                yield return new TestCaseData(@"\\a\b").Returns(@"\\a\b");
                yield return new TestCaseData(@"\\a\b\").Returns(@"\\a\b");
                yield return new TestCaseData(@"\\a\b\c").Returns(@"\\a\b");
                yield return new TestCaseData(@"\\a\b\c\").Returns(@"\\a\b");

                yield return new TestCaseData(@"/").Returns(@"\");
                yield return new TestCaseData(@"/a").Returns(@"\");
                yield return new TestCaseData(@"/a\b").Returns(@"\");
                yield return new TestCaseData(@"/a\b\c").Returns(@"\");
                yield return new TestCaseData(@"/a\b\c\d").Returns(@"\");
                yield return new TestCaseData(@"//").Returns(@"\\");
                yield return new TestCaseData(@"//a").Returns(@"\\a");
                yield return new TestCaseData(@"//a/").Returns(@"\\a\");
                yield return new TestCaseData(@"//a/b").Returns(@"\\a\b");
                yield return new TestCaseData(@"//a/b/").Returns(@"\\a\b");
                yield return new TestCaseData(@"//a/b/c").Returns(@"\\a\b");
                yield return new TestCaseData(@"//a/b/c/").Returns(@"\\a\b");
            }
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetRandomFileName()
        {
            string randomFilename = PathUtility.GetRandomFileName();

            Assert.That(randomFilename, Is.Not.Null);
            Assert.That(randomFilename, Is.Not.Empty);
            Assert.That(randomFilename.Length, Is.GreaterThan(3));
            Assert.That(randomFilename.Contains("."), Is.True);
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetTempFileName()
        {
            string tempFileName = PathUtility.GetTempFileName();

            Assert.That(tempFileName, Is.Not.Null);
            Assert.That(tempFileName, Is.Not.Empty);
            Assert.That(tempFileName.Length, Is.GreaterThan(3));
            Assert.That(tempFileName.Contains("."), Is.True);
        }

        [Category("UnitTest")]
        [Test]
        public void CanGetTempPath()
        {
            string tempPath = PathUtility.GetTempPath();

            Assert.That(tempPath, Is.Not.Null);
            Assert.That(tempPath, Is.Not.Empty);
            Assert.That(tempPath.Length, Is.GreaterThan(3));
            Assert.That(tempPath.Contains("."), Is.False);
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForHasExtension")]
        public bool HasExtension(string path)
        {
            bool value = PathUtility.HasExtension(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForHasExtension
        {
            get
            {
                yield return new TestCaseData(null).Returns(false);
                yield return new TestCaseData("").Returns(false);
                yield return new TestCaseData(".").Returns(false);
                yield return new TestCaseData("..").Returns(false);
                yield return new TestCaseData("...").Returns(false);
                yield return new TestCaseData("....").Returns(false);
                yield return new TestCaseData(".....").Returns(false);
                yield return new TestCaseData("a").Returns(false);
                yield return new TestCaseData("a.").Returns(false);
                yield return new TestCaseData(".a").Returns(true);
                yield return new TestCaseData(".ab").Returns(true);
                yield return new TestCaseData(".abc").Returns(true);
                yield return new TestCaseData(".abcd").Returns(true);
                yield return new TestCaseData(".abcde").Returns(true);
                yield return new TestCaseData(".abcdef").Returns(true);
                yield return new TestCaseData("0.a").Returns(true);
                yield return new TestCaseData("0.ab").Returns(true);
                yield return new TestCaseData("0.abc").Returns(true);
                yield return new TestCaseData("0.abcd").Returns(true);
                yield return new TestCaseData("0.abcde").Returns(true);
                yield return new TestCaseData("0.abcdef").Returns(true);
                yield return new TestCaseData("a.b").Returns(true);
                yield return new TestCaseData("a.b.c").Returns(true);
                yield return new TestCaseData("filename.ext").Returns(true);
                yield return new TestCaseData(@"dir\filename.ext").Returns(true);
                yield return new TestCaseData("dotted.filename.ext").Returns(true);
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(true);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForIsPathRooted")]
        public bool IsPathRooted(string path)
        {
            bool value = PathUtility.IsPathRooted(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForIsPathRooted
        {
            get
            {
                yield return new TestCaseData(null).Returns(false);
                yield return new TestCaseData("").Returns(false);
                yield return new TestCaseData(".").Returns(false);
                yield return new TestCaseData("..").Returns(false);
                yield return new TestCaseData("...").Returns(false);
                yield return new TestCaseData("....").Returns(false);
                yield return new TestCaseData(".....").Returns(false);
                yield return new TestCaseData("a").Returns(false);
                yield return new TestCaseData("a.").Returns(false);
                yield return new TestCaseData(".a").Returns(false);
                yield return new TestCaseData(".ab").Returns(false);
                yield return new TestCaseData(".abc").Returns(false);
                yield return new TestCaseData(".abcd").Returns(false);
                yield return new TestCaseData(".abcde").Returns(false);
                yield return new TestCaseData(".abcdef").Returns(false);
                yield return new TestCaseData("0.a").Returns(false);
                yield return new TestCaseData("0.ab").Returns(false);
                yield return new TestCaseData("0.abc").Returns(false);
                yield return new TestCaseData("0.abcd").Returns(false);
                yield return new TestCaseData("0.abcde").Returns(false);
                yield return new TestCaseData("0.abcdef").Returns(false);
                yield return new TestCaseData("a.b").Returns(false);
                yield return new TestCaseData("a.b.c").Returns(false);
                yield return new TestCaseData("filename.ext").Returns(false);
                yield return new TestCaseData(@"dir\filename.ext").Returns(false);
                yield return new TestCaseData("dotted.filename.ext").Returns(false);
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(false);

                yield return new TestCaseData("C:").Returns(true);
                yield return new TestCaseData(@"C:\").Returns(true);
                yield return new TestCaseData(@"C:\a").Returns(true);
                yield return new TestCaseData(@"C:\a\").Returns(true);
                yield return new TestCaseData(@"C:\a\b").Returns(true);
                yield return new TestCaseData(@"C:\a\b\").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c\").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c\d").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c\d\").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c\d\e").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c\d\e\").Returns(true);

                yield return new TestCaseData(@"\").Returns(true);
                yield return new TestCaseData(@"\a").Returns(true);
                yield return new TestCaseData(@"\a\b").Returns(true);
                yield return new TestCaseData(@"\a\b\c").Returns(true);
                yield return new TestCaseData(@"\a\b\c\d").Returns(true);
                yield return new TestCaseData(@"\\").Returns(true);
                yield return new TestCaseData(@"\\a").Returns(true);
                yield return new TestCaseData(@"\\a\").Returns(true);
                yield return new TestCaseData(@"\\a\b").Returns(true);
                yield return new TestCaseData(@"\\a\b\").Returns(true);
                yield return new TestCaseData(@"\\a\b\c").Returns(true);
                yield return new TestCaseData(@"\\a\b\c\").Returns(true);

                yield return new TestCaseData(@"/").Returns(true);
                yield return new TestCaseData(@"/a").Returns(true);
                yield return new TestCaseData(@"/a\b").Returns(true);
                yield return new TestCaseData(@"/a\b\c").Returns(true);
                yield return new TestCaseData(@"/a\b\c\d").Returns(true);
                yield return new TestCaseData(@"//").Returns(true);
                yield return new TestCaseData(@"//a").Returns(true);
                yield return new TestCaseData(@"//a/").Returns(true);
                yield return new TestCaseData(@"//a/b").Returns(true);
                yield return new TestCaseData(@"//a/b/").Returns(true);
                yield return new TestCaseData(@"//a/b/c").Returns(true);
                yield return new TestCaseData(@"//a/b/c/").Returns(true);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForContainsInvalidCharacters")]
        public bool ContainsInvalidCharacters(string path)
        {
            bool value = PathUtility.ContainsInvalidCharacters(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForContainsInvalidCharacters
        {
            get
            {
                char[] invalidCharacters = PathUtility.GetInvalidPathChars();

                foreach (char invalidFileNameCharacter in invalidCharacters)
                {
                    yield return new TestCaseData(invalidFileNameCharacter.ToString()).Returns(true);
                }

                yield return new TestCaseData(null).Returns(false);
                yield return new TestCaseData("").Returns(false);
                yield return new TestCaseData(".").Returns(false);
                yield return new TestCaseData("..").Returns(false);
                yield return new TestCaseData("...").Returns(false);
                yield return new TestCaseData("....").Returns(false);
                yield return new TestCaseData(".....").Returns(false);
                yield return new TestCaseData("a").Returns(false);
                yield return new TestCaseData("a.").Returns(false);
                yield return new TestCaseData(".a").Returns(false);
                yield return new TestCaseData(".ab").Returns(false);
                yield return new TestCaseData(".abc").Returns(false);
                yield return new TestCaseData(".abcd").Returns(false);
                yield return new TestCaseData(".abcde").Returns(false);
                yield return new TestCaseData(".abcdef").Returns(false);
                yield return new TestCaseData("0.a").Returns(false);
                yield return new TestCaseData("0.ab").Returns(false);
                yield return new TestCaseData("0.abc").Returns(false);
                yield return new TestCaseData("0.abcd").Returns(false);
                yield return new TestCaseData("0.abcde").Returns(false);
                yield return new TestCaseData("0.abcdef").Returns(false);
                yield return new TestCaseData("a.b").Returns(false);
                yield return new TestCaseData("a.b.c").Returns(false);
                yield return new TestCaseData("filename.ext").Returns(false);
                yield return new TestCaseData(@"dir\filename.ext").Returns(false);
                yield return new TestCaseData("dotted.filename.ext").Returns(false);
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(false);

                yield return new TestCaseData("C:").Returns(false);
                yield return new TestCaseData(@"C:\").Returns(false);
                yield return new TestCaseData(@"C:\a").Returns(false);
                yield return new TestCaseData(@"C:\a\").Returns(false);
                yield return new TestCaseData(@"C:\a\b").Returns(false);
                yield return new TestCaseData(@"C:\a\b\").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c\").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c\d").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c\d\").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c\d\e").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c\d\e\").Returns(false);

                yield return new TestCaseData(@"\").Returns(false);
                yield return new TestCaseData(@"\a").Returns(false);
                yield return new TestCaseData(@"\a\b").Returns(false);
                yield return new TestCaseData(@"\a\b\c").Returns(false);
                yield return new TestCaseData(@"\a\b\c\d").Returns(false);
                yield return new TestCaseData(@"\\").Returns(false);
                yield return new TestCaseData(@"\\a").Returns(false);
                yield return new TestCaseData(@"\\a\").Returns(false);
                yield return new TestCaseData(@"\\a\b").Returns(false);
                yield return new TestCaseData(@"\\a\b\").Returns(false);
                yield return new TestCaseData(@"\\a\b\c").Returns(false);
                yield return new TestCaseData(@"\\a\b\c\").Returns(false);

                yield return new TestCaseData(@"/").Returns(false);
                yield return new TestCaseData(@"/a").Returns(false);
                yield return new TestCaseData(@"/a\b").Returns(false);
                yield return new TestCaseData(@"/a\b\c").Returns(false);
                yield return new TestCaseData(@"/a\b\c\d").Returns(false);
                yield return new TestCaseData(@"//").Returns(false);
                yield return new TestCaseData(@"//a").Returns(false);
                yield return new TestCaseData(@"//a/").Returns(false);
                yield return new TestCaseData(@"//a/b").Returns(false);
                yield return new TestCaseData(@"//a/b/").Returns(false);
                yield return new TestCaseData(@"//a/b/c").Returns(false);
                yield return new TestCaseData(@"//a/b/c/").Returns(false);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForContainsSpecifiedCharacters")]
        public bool ContainsSpecifiedCharacters(string path, char[] specifiedCharacters)
        {
            bool value = PathUtility.ContainsSpecifiedCharacters(path, specifiedCharacters);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForContainsSpecifiedCharacters
        {
            get
            {
                yield return new TestCaseData(null, null).Throws(typeof (ArgumentNullException));
                yield return new TestCaseData("", null).Throws(typeof (ArgumentNullException));
                yield return new TestCaseData("a", null).Throws(typeof (ArgumentNullException));
                yield return new TestCaseData("a", new char[] { }).Throws(typeof(ArgumentException));
                yield return new TestCaseData("", new[] { 'a' }).Returns(false);
                yield return new TestCaseData("b", new[] { 'a' }).Returns(false);
                yield return new TestCaseData("abc", new[] { 'a' }).Returns(true);
                yield return new TestCaseData("abc", new[] { 'b' }).Returns(true);
                yield return new TestCaseData("abc", new[] { 'c' }).Returns(true);
                yield return new TestCaseData("abc", new[] { ' ' }).Returns(false);
                yield return new TestCaseData("abc", new[] { 'd' }).Returns(false);
                yield return new TestCaseData("filename.ext", new[] { '.' }).Returns(true);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForEndsWithDirectorySeparator")]
        public bool EndsWithDirectorySeparator(string path)
        {
            bool value = PathUtility.EndsWithDirectorySeparator(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForEndsWithDirectorySeparator
        {
            get
            {
                yield return new TestCaseData(null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("").Throws(typeof(ArgumentException));

                // Generate whitespace values to test.
                for (int i = 1; i < 11; i++)
                {
                    foreach (char whitespaceChar in _whitespaceChars)
                    {
                        string whitespacePath = new string(whitespaceChar, i);
                        yield return new TestCaseData(whitespacePath).Throws(typeof(ArgumentException));
                    }
                }

                yield return new TestCaseData("a").Returns(false);
                yield return new TestCaseData("ab").Returns(false);
                yield return new TestCaseData("abc").Returns(false);
                yield return new TestCaseData("abcd").Returns(false);
                yield return new TestCaseData("abcde").Returns(false);
                yield return new TestCaseData(@"a\b").Returns(false);
                yield return new TestCaseData(@"a\b\c").Returns(false);
                yield return new TestCaseData(@"a\b\c\d").Returns(false);
                yield return new TestCaseData(@"a\b\c\d\e").Returns(false);

                yield return new TestCaseData(@"\").Returns(true);
                yield return new TestCaseData(@"a\").Returns(true);
                yield return new TestCaseData(@"a\b\").Returns(true);
                yield return new TestCaseData(@"a\b\c\").Returns(true);
                yield return new TestCaseData(@"a\b\c\d\").Returns(true);
                yield return new TestCaseData(@"a\b\c\d\e\").Returns(true);

                yield return new TestCaseData(@"/").Returns(false);
                yield return new TestCaseData(@"a/").Returns(false);
                yield return new TestCaseData(@"a/b/").Returns(false);
                yield return new TestCaseData(@"a/b/c/").Returns(false);
                yield return new TestCaseData(@"a/b/c/d/").Returns(false);
                yield return new TestCaseData(@"a/b/c/d/e/").Returns(false);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanEnsurePathEndsWithDirectorySeparator")]
        public string CanEnsurePathEndsWithDirectorySeparator(string path)
        {
            string value = PathUtility.EnsurePathEndsWithDirectorySeparator(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanEnsurePathEndsWithDirectorySeparator
        {
            get
            {
                yield return new TestCaseData(null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("").Throws(typeof(ArgumentException));

                // Generate whitespace values to test.
                for (int i = 1; i < 11; i++)
                {
                    foreach (char whitespaceChar in _whitespaceChars)
                    {
                        string whitespacePath = new string(whitespaceChar, i);
                        yield return new TestCaseData(whitespacePath).Throws(typeof(ArgumentException));
                    }
                }

                yield return new TestCaseData("a").Returns(@"a\");
                yield return new TestCaseData("ab").Returns(@"ab\");
                yield return new TestCaseData("abc").Returns(@"abc\");
                yield return new TestCaseData("abcd").Returns(@"abcd\");
                yield return new TestCaseData("abcde").Returns(@"abcde\");
                yield return new TestCaseData(@"a\b").Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\e").Returns(@"a\b\c\d\e\");

                yield return new TestCaseData(@"\").Returns(@"\");
                yield return new TestCaseData(@"a\").Returns(@"a\");
                yield return new TestCaseData(@"a\b\").Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c\").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d\").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\e\").Returns(@"a\b\c\d\e\");

                yield return new TestCaseData(@"/").Returns(@"/\");
                yield return new TestCaseData(@"a/").Returns(@"a/\");
                yield return new TestCaseData(@"a/b/").Returns(@"a/b/\");
                yield return new TestCaseData(@"a/b/c/").Returns(@"a/b/c/\");
                yield return new TestCaseData(@"a/b/c/d/").Returns(@"a/b/c/d/\");
                yield return new TestCaseData(@"a/b/c/d/e/").Returns(@"a/b/c/d/e/\");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanEnsurePathEndsWithDirectorySeparatorWithSpecificDirectorySeparator")]
        public string CanEnsurePathEndsWithDirectorySeparatorWithSpecificDirectorySeparator(string path, string directorySeparator)
        {
            string value = PathUtility.EnsurePathEndsWithDirectorySeparator(path, directorySeparator);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanEnsurePathEndsWithDirectorySeparatorWithSpecificDirectorySeparator
        {
            get
            {
                yield return new TestCaseData(null, @"\").Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", @"\").Throws(typeof(ArgumentException));

                // Generate whitespace values to test.
                for (int i = 1; i < 11; i++)
                {
                    foreach (char whitespaceChar in _whitespaceChars)
                    {
                        string whitespacePath = new string(whitespaceChar, i);
                        yield return new TestCaseData(whitespacePath, @"\").Throws(typeof(ArgumentException));
                    }
                }

                yield return new TestCaseData("a", null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("a", "").Throws(typeof(ArgumentException));
                yield return new TestCaseData("a", @"\").Returns(@"a\");
                yield return new TestCaseData("ab", @"\").Returns(@"ab\");
                yield return new TestCaseData("abc", @"\").Returns(@"abc\");
                yield return new TestCaseData("abcd", @"\").Returns(@"abcd\");
                yield return new TestCaseData("abcde", @"\").Returns(@"abcde\");
                yield return new TestCaseData(@"a\b", @"\").Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c", @"\").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d", @"\").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\e", @"\").Returns(@"a\b\c\d\e\");

                yield return new TestCaseData(@"\", @"\").Returns(@"\");
                yield return new TestCaseData(@"a\", @"\").Returns(@"a\");
                yield return new TestCaseData(@"a\b\", @"\").Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c\", @"\").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d\", @"\").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\e\", @"\").Returns(@"a\b\c\d\e\");

                yield return new TestCaseData(@"/", @"\").Returns(@"/\");
                yield return new TestCaseData(@"a/", @"\").Returns(@"a/\");
                yield return new TestCaseData(@"a/b/", @"\").Returns(@"a/b/\");
                yield return new TestCaseData(@"a/b/c/", @"\").Returns(@"a/b/c/\");
                yield return new TestCaseData(@"a/b/c/d/", @"\").Returns(@"a/b/c/d/\");
                yield return new TestCaseData(@"a/b/c/d/e/", @"\").Returns(@"a/b/c/d/e/\");

                yield return new TestCaseData("a", @"/").Returns(@"a/");
                yield return new TestCaseData("ab", @"/").Returns(@"ab/");
                yield return new TestCaseData("abc", @"/").Returns(@"abc/");
                yield return new TestCaseData("abcd", @"/").Returns(@"abcd/");
                yield return new TestCaseData("abcde", @"/").Returns(@"abcde/");
                yield return new TestCaseData(@"a\b", @"/").Returns(@"a\b/");
                yield return new TestCaseData(@"a\b\c", @"/").Returns(@"a\b\c/");
                yield return new TestCaseData(@"a\b\c\d", @"/").Returns(@"a\b\c\d/");
                yield return new TestCaseData(@"a\b\c\d\e", @"/").Returns(@"a\b\c\d\e/");

                yield return new TestCaseData(@"\", @"/").Returns(@"\/");
                yield return new TestCaseData(@"a\", @"/").Returns(@"a\/");
                yield return new TestCaseData(@"a\b\", @"/").Returns(@"a\b\/");
                yield return new TestCaseData(@"a\b\c\", @"/").Returns(@"a\b\c\/");
                yield return new TestCaseData(@"a\b\c\d\", @"/").Returns(@"a\b\c\d\/");
                yield return new TestCaseData(@"a\b\c\d\e\", @"/").Returns(@"a\b\c\d\e\/");

                yield return new TestCaseData(@"/", @"/").Returns(@"/");
                yield return new TestCaseData(@"a/", @"/").Returns(@"a/");
                yield return new TestCaseData(@"a/b/", @"/").Returns(@"a/b/");
                yield return new TestCaseData(@"a/b/c/", @"/").Returns(@"a/b/c/");
                yield return new TestCaseData(@"a/b/c/d/", @"/").Returns(@"a/b/c/d/");
                yield return new TestCaseData(@"a/b/c/d/e/", @"/").Returns(@"a/b/c/d/e/");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanEnsurePathEndsWithDirectorySeparatorWithSpecificDirectorySeparatorChar")]
        public string CanEnsurePathEndsWithDirectorySeparatorWithSpecificDirectorySeparatorChar(string path, char directorySeparatorChar)
        {
            string value = PathUtility.EnsurePathEndsWithDirectorySeparatorChar(path, directorySeparatorChar);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanEnsurePathEndsWithDirectorySeparatorWithSpecificDirectorySeparatorChar
        {
            get
            {
                yield return new TestCaseData(null, '\\').Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("", '\\').Throws(typeof(ArgumentException));

                // Generate whitespace values to test.
                for (int i = 1; i < 11; i++)
                {
                    foreach (char whitespaceChar in _whitespaceChars)
                    {
                        string whitespacePath = new string(whitespaceChar, i);
                        yield return new TestCaseData(whitespacePath, "\\").Throws(typeof(ArgumentException));
                    }
                }

                yield return new TestCaseData("a", '\\').Returns(@"a\");
                yield return new TestCaseData("ab", '\\').Returns(@"ab\");
                yield return new TestCaseData("abc", '\\').Returns(@"abc\");
                yield return new TestCaseData("abcd", '\\').Returns(@"abcd\");
                yield return new TestCaseData("abcde", '\\').Returns(@"abcde\");
                yield return new TestCaseData(@"a\b", '\\').Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c", '\\').Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d", '\\').Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\e", '\\').Returns(@"a\b\c\d\e\");

                yield return new TestCaseData(@"\", '\\').Returns(@"\");
                yield return new TestCaseData(@"a\", '\\').Returns(@"a\");
                yield return new TestCaseData(@"a\b\", '\\').Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c\", '\\').Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d\", '\\').Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\e\", '\\').Returns(@"a\b\c\d\e\");

                yield return new TestCaseData(@"/", '\\').Returns(@"/\");
                yield return new TestCaseData(@"a/", '\\').Returns(@"a/\");
                yield return new TestCaseData(@"a/b/", '\\').Returns(@"a/b/\");
                yield return new TestCaseData(@"a/b/c/", '\\').Returns(@"a/b/c/\");
                yield return new TestCaseData(@"a/b/c/d/", '\\').Returns(@"a/b/c/d/\");
                yield return new TestCaseData(@"a/b/c/d/e/", '\\').Returns(@"a/b/c/d/e/\");

                yield return new TestCaseData("a", '/').Returns(@"a/");
                yield return new TestCaseData("ab", '/').Returns(@"ab/");
                yield return new TestCaseData("abc", '/').Returns(@"abc/");
                yield return new TestCaseData("abcd", '/').Returns(@"abcd/");
                yield return new TestCaseData("abcde", '/').Returns(@"abcde/");
                yield return new TestCaseData(@"a\b", '/').Returns(@"a\b/");
                yield return new TestCaseData(@"a\b\c", '/').Returns(@"a\b\c/");
                yield return new TestCaseData(@"a\b\c\d", '/').Returns(@"a\b\c\d/");
                yield return new TestCaseData(@"a\b\c\d\e", '/').Returns(@"a\b\c\d\e/");

                yield return new TestCaseData(@"\", '/').Returns(@"\/");
                yield return new TestCaseData(@"a\", '/').Returns(@"a\/");
                yield return new TestCaseData(@"a\b\", '/').Returns(@"a\b\/");
                yield return new TestCaseData(@"a\b\c\", '/').Returns(@"a\b\c\/");
                yield return new TestCaseData(@"a\b\c\d\", '/').Returns(@"a\b\c\d\/");
                yield return new TestCaseData(@"a\b\c\d\e\", '/').Returns(@"a\b\c\d\e\/");

                yield return new TestCaseData(@"/", '/').Returns(@"/");
                yield return new TestCaseData(@"a/", '/').Returns(@"a/");
                yield return new TestCaseData(@"a/b/", '/').Returns(@"a/b/");
                yield return new TestCaseData(@"a/b/c/", '/').Returns(@"a/b/c/");
                yield return new TestCaseData(@"a/b/c/d/", '/').Returns(@"a/b/c/d/");
                yield return new TestCaseData(@"a/b/c/d/e/", '/').Returns(@"a/b/c/d/e/");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForIsPathRoot")]
        public bool IsPathRoot(string path)
        {
            bool value = PathUtility.IsPathRoot(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForIsPathRoot
        {
            get
            {
                yield return new TestCaseData(null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("").Throws(typeof(ArgumentException));
                
                // Generate whitespace values to test.
                for (int i = 1; i < 11; i++)
                {
                    foreach (char whitespaceChar in _whitespaceChars)
                    {
                        string whitespacePath = new string(whitespaceChar, i);
                        yield return new TestCaseData(whitespacePath).Throws(typeof(ArgumentException));
                    }
                }

                yield return new TestCaseData(".").Returns(false);
                yield return new TestCaseData("..").Returns(false);
                yield return new TestCaseData("...").Returns(false);
                yield return new TestCaseData("....").Returns(false);
                yield return new TestCaseData(".....").Returns(false);
                yield return new TestCaseData("a").Returns(false);
                yield return new TestCaseData("a.").Returns(false);
                yield return new TestCaseData(".a").Returns(false);
                yield return new TestCaseData(".ab").Returns(false);
                yield return new TestCaseData(".abc").Returns(false);
                yield return new TestCaseData(".abcd").Returns(false);
                yield return new TestCaseData(".abcde").Returns(false);
                yield return new TestCaseData(".abcdef").Returns(false);
                yield return new TestCaseData("0.a").Returns(false);
                yield return new TestCaseData("0.ab").Returns(false);
                yield return new TestCaseData("0.abc").Returns(false);
                yield return new TestCaseData("0.abcd").Returns(false);
                yield return new TestCaseData("0.abcde").Returns(false);
                yield return new TestCaseData("0.abcdef").Returns(false);
                yield return new TestCaseData("a.b").Returns(false);
                yield return new TestCaseData("a.b.c").Returns(false);
                yield return new TestCaseData("filename.ext").Returns(false);
                yield return new TestCaseData(@"dir\filename.ext").Returns(false);
                yield return new TestCaseData("dotted.filename.ext").Returns(false);
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(false);
                
                yield return new TestCaseData("C:").Returns(true);
                yield return new TestCaseData(@"C:\").Returns(true);
                yield return new TestCaseData(@"C:\a").Returns(false);
                yield return new TestCaseData(@"C:\a\").Returns(false);
                yield return new TestCaseData(@"C:\a\b").Returns(false);
                yield return new TestCaseData(@"C:\a\b\").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c").Returns(false);
                yield return new TestCaseData(@"C:\a\b\c\").Returns(false);

                yield return new TestCaseData(@"\\").Returns(true);
                yield return new TestCaseData(@"\\a").Returns(true);
                yield return new TestCaseData(@"\\a\").Returns(true);
                yield return new TestCaseData(@"\\a\b").Returns(true);
                yield return new TestCaseData(@"\\a\b\").Returns(false);
                yield return new TestCaseData(@"\\a\b\c").Returns(false);
                yield return new TestCaseData(@"\\a\b\c\").Returns(false);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForIsPathValid")]
        public bool IsPathValid(string path)
        {
            bool value = PathUtility.IsPathValid(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForIsPathValid
        {
            get
            {
                char[] invalidCharacters = PathUtility.GetInvalidPathChars();

                foreach (char invalidFileNameCharacter in invalidCharacters)
                {
                    yield return new TestCaseData(invalidFileNameCharacter.ToString()).Returns(false);
                }

                yield return new TestCaseData(null).Returns(false);
                yield return new TestCaseData("").Returns(false);
                yield return new TestCaseData(".").Returns(true);
                yield return new TestCaseData("..").Returns(true);
                yield return new TestCaseData("...").Returns(true);
                yield return new TestCaseData("....").Returns(true);
                yield return new TestCaseData(".....").Returns(true);
                yield return new TestCaseData("a").Returns(true);
                yield return new TestCaseData("a.").Returns(true);
                yield return new TestCaseData(".a").Returns(true);
                yield return new TestCaseData(".ab").Returns(true);
                yield return new TestCaseData(".abc").Returns(true);
                yield return new TestCaseData(".abcd").Returns(true);
                yield return new TestCaseData(".abcde").Returns(true);
                yield return new TestCaseData(".abcdef").Returns(true);
                yield return new TestCaseData("0.a").Returns(true);
                yield return new TestCaseData("0.ab").Returns(true);
                yield return new TestCaseData("0.abc").Returns(true);
                yield return new TestCaseData("0.abcd").Returns(true);
                yield return new TestCaseData("0.abcde").Returns(true);
                yield return new TestCaseData("0.abcdef").Returns(true);
                yield return new TestCaseData("a.b").Returns(true);
                yield return new TestCaseData("a.b.c").Returns(true);
                yield return new TestCaseData("filename.ext").Returns(true);
                yield return new TestCaseData(@"dir\filename.ext").Returns(true);
                yield return new TestCaseData("dotted.filename.ext").Returns(true);
                yield return new TestCaseData(@"dir\dotted.filename.ext").Returns(true);

                yield return new TestCaseData("C:").Returns(true);
                yield return new TestCaseData(@"C:\").Returns(true);
                yield return new TestCaseData(@"C:\a").Returns(true);
                yield return new TestCaseData(@"C:\a\").Returns(true);
                yield return new TestCaseData(@"C:\a\b").Returns(true);
                yield return new TestCaseData(@"C:\a\b\").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c").Returns(true);
                yield return new TestCaseData(@"C:\a\b\c\").Returns(true);

                yield return new TestCaseData(@"\\").Returns(true);
                yield return new TestCaseData(@"\\a").Returns(true);
                yield return new TestCaseData(@"\\a\").Returns(true);
                yield return new TestCaseData(@"\\a\b").Returns(true);
                yield return new TestCaseData(@"\\a\b\").Returns(true);
                yield return new TestCaseData(@"\\a\b\c").Returns(true);
                yield return new TestCaseData(@"\\a\b\c\").Returns(true);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetLastPathPart")]
        public string CanGetLastPathPart(string path)
        {
            string value = PathUtility.GetLastPathPart(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetLastPathPart
        {
            get
            {
                yield return new TestCaseData(null).Throws(typeof(ArgumentNullException));
                yield return new TestCaseData("").Throws(typeof(ArgumentException));

                // Generate whitespace values to test.
                for (int i = 1; i < 11; i++)
                {
                    foreach (char whitespaceChar in _whitespaceChars)
                    {
                        string whitespacePath = new string(whitespaceChar, i);
                        yield return new TestCaseData(whitespacePath).Throws(typeof(ArgumentException));
                    }
                }

                yield return new TestCaseData("a").Returns("a");
                yield return new TestCaseData(@"a\b").Returns("b");
                yield return new TestCaseData(@"a\b\").Returns(string.Empty);
                yield return new TestCaseData(@"a\b\c").Returns(@"c");
                yield return new TestCaseData(@"a\b\c\").Returns(string.Empty);
                yield return new TestCaseData(@"a\b\c\d").Returns(@"d");
                yield return new TestCaseData(@"a\b\c\d\").Returns(string.Empty);
                yield return new TestCaseData(@"a\b\c\d\\").Returns(string.Empty);
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanGetParentPath")]
        public string CanGetParentPath(string path)
        {
            string value = PathUtility.GetParentPath(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanGetParentPath
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Returns(string.Empty);
                yield return new TestCaseData("a").Returns("a");
                yield return new TestCaseData(@"a\b").Returns("a");
                yield return new TestCaseData(@"a\b\").Returns("a");
                yield return new TestCaseData(@"a\b\c").Returns(@"a\b");
                yield return new TestCaseData(@"a\b\c\").Returns(@"a\b");
                yield return new TestCaseData(@"a\b\c\d").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\b\c\d\").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\b\c\d\\").Returns(@"a\b\c\d");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanResolveRelativePathParts")]
        public string CanResolveRelativePathParts(string path)
        {
            string value = PathUtility.ResolveRelativePathParts(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanResolveRelativePathParts
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Returns(string.Empty);
                yield return new TestCaseData("a").Returns("a");
                yield return new TestCaseData(@"a\b").Returns(@"a\b");
                yield return new TestCaseData(@"a\b\").Returns(@"a\b\");
                yield return new TestCaseData(@"a\b\c").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\b\c\").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\c\d").Returns(@"a\b\c\d");
                yield return new TestCaseData(@"a\b\c\d\").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\d\\").Returns(@"a\b\c\d\\");

                yield return new TestCaseData(@".").Returns(string.Empty);
                yield return new TestCaseData(@"a\.\b").Returns(@"a\b");
                yield return new TestCaseData(@"a\.\b\").Returns(@"a\b\");
                yield return new TestCaseData(@"a\.\b\c").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\.\b\c\").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\.\b\c\d").Returns(@"a\b\c\d");
                yield return new TestCaseData(@"a\.\b\c\d\").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\.\c").Returns(@"a\b\c");
                yield return new TestCaseData(@"a\b\.\c\").Returns(@"a\b\c\");
                yield return new TestCaseData(@"a\b\.\c\d").Returns(@"a\b\c\d");
                yield return new TestCaseData(@"a\b\.\c\d\").Returns(@"a\b\c\d\");
                yield return new TestCaseData(@"a\b\c\.\d").Returns(@"a\b\c\d");
                yield return new TestCaseData(@"a\b\c\.\d\").Returns(@"a\b\c\d\");

                yield return new TestCaseData(@"..").Throws(typeof(ArgumentException));
                yield return new TestCaseData(@"a\..").Returns(string.Empty);
                yield return new TestCaseData(@"a\..\").Returns(@"\");
                yield return new TestCaseData(@"a\..\b").Returns(@"b");
                yield return new TestCaseData(@"a\..\b\").Returns(@"b\");
                yield return new TestCaseData(@"a\..\b\c").Returns(@"b\c");
                yield return new TestCaseData(@"a\..\b\c\").Returns(@"b\c\");
                yield return new TestCaseData(@"a\..\b\c\d").Returns(@"b\c\d");
                yield return new TestCaseData(@"a\..\b\c\d\").Returns(@"b\c\d\");
                yield return new TestCaseData(@"a\b\..\c").Returns(@"a\c");
                yield return new TestCaseData(@"a\b\..\c\").Returns(@"a\c\");
                yield return new TestCaseData(@"a\b\..\c\d").Returns(@"a\c\d");
                yield return new TestCaseData(@"a\b\..\c\d\").Returns(@"a\c\d\");
                yield return new TestCaseData(@"a\b\c\..\d").Returns(@"a\b\d");
                yield return new TestCaseData(@"a\b\c\..\d\").Returns(@"a\b\d\");
            }
        }

        [Category("UnitTest")]
        [Test]
        [TestCaseSource("TestCasesForCanResolveRelativeWebPathParts")]
        public string CanResolveRelativeWebPathParts(string path)
        {
            string value = PathUtility.ResolveRelativeWebPathParts(path);
            return value;
        }

        public static IEnumerable<TestCaseData> TestCasesForCanResolveRelativeWebPathParts
        {
            get
            {
                yield return new TestCaseData(null).Returns(null);
                yield return new TestCaseData("").Returns(string.Empty);
                yield return new TestCaseData("a").Returns("a");
                yield return new TestCaseData(@"a/b").Returns(@"a/b");
                yield return new TestCaseData(@"a/b/").Returns(@"a/b/");
                yield return new TestCaseData(@"a/b/c").Returns(@"a/b/c");
                yield return new TestCaseData(@"a/b/c/").Returns(@"a/b/c/");
                yield return new TestCaseData(@"a/b/c/d").Returns(@"a/b/c/d");
                yield return new TestCaseData(@"a/b/c/d/").Returns(@"a/b/c/d/");
                yield return new TestCaseData(@"a/b/c/d//").Returns(@"a/b/c/d//");

                yield return new TestCaseData(@".").Returns(string.Empty);
                yield return new TestCaseData(@"a/./b").Returns(@"a/b");
                yield return new TestCaseData(@"a/./b/").Returns(@"a/b/");
                yield return new TestCaseData(@"a/./b/c").Returns(@"a/b/c");
                yield return new TestCaseData(@"a/./b/c/").Returns(@"a/b/c/");
                yield return new TestCaseData(@"a/./b/c/d").Returns(@"a/b/c/d");
                yield return new TestCaseData(@"a/./b/c/d/").Returns(@"a/b/c/d/");
                yield return new TestCaseData(@"a/b/./c").Returns(@"a/b/c");
                yield return new TestCaseData(@"a/b/./c/").Returns(@"a/b/c/");
                yield return new TestCaseData(@"a/b/./c/d").Returns(@"a/b/c/d");
                yield return new TestCaseData(@"a/b/./c/d/").Returns(@"a/b/c/d/");
                yield return new TestCaseData(@"a/b/c/./d").Returns(@"a/b/c/d");
                yield return new TestCaseData(@"a/b/c/./d/").Returns(@"a/b/c/d/");

                yield return new TestCaseData(@"..").Throws(typeof(ArgumentException));
                yield return new TestCaseData(@"a/..").Returns(string.Empty);
                yield return new TestCaseData(@"a/../").Returns(@"/");
                yield return new TestCaseData(@"a/../b").Returns(@"b");
                yield return new TestCaseData(@"a/../b/").Returns(@"b/");
                yield return new TestCaseData(@"a/../b/c").Returns(@"b/c");
                yield return new TestCaseData(@"a/../b/c/").Returns(@"b/c/");
                yield return new TestCaseData(@"a/../b/c/d").Returns(@"b/c/d");
                yield return new TestCaseData(@"a/../b/c/d/").Returns(@"b/c/d/");
                yield return new TestCaseData(@"a/b/../c").Returns(@"a/c");
                yield return new TestCaseData(@"a/b/../c/").Returns(@"a/c/");
                yield return new TestCaseData(@"a/b/../c/d").Returns(@"a/c/d");
                yield return new TestCaseData(@"a/b/../c/d/").Returns(@"a/c/d/");
                yield return new TestCaseData(@"a/b/c/../d").Returns(@"a/b/d");
                yield return new TestCaseData(@"a/b/c/../d/").Returns(@"a/b/d/");
            }
        }
    }
}